package xaj.meta;

import java.io.Reader;
import java.util.Collection;
import java.util.List;


import xaj.meta.parse.Grm;
import xaj.meta.parse.Lexer_c;
import xaj.scc.types.SCTypeSystem_c;
import xaj.meta.visit.Visitor_Dudu_01;
import xaj.meta.visit.Visitor_Dudu_02;
import xaj.meta.visit.Visitor_Giorgio_01;
import xaj.scc.ast.SCNodeFactory_c;

import polyglot.ast.NodeFactory;
import polyglot.frontend.CupParser;
import polyglot.frontend.FileSource;
import polyglot.frontend.GlobalBarrierPass;
import polyglot.frontend.Job;
import polyglot.frontend.OutputPass;
import polyglot.frontend.Parser;
import polyglot.frontend.Pass;
import polyglot.frontend.VisitorPass;
import polyglot.frontend.Pass.ID;
import polyglot.lex.Lexer;
import polyglot.parse.BaseParser;
import polyglot.types.TypeSystem;
import polyglot.util.ErrorQueue;
import polyglot.visit.Translator;

public class ExtensionInfo extends abc.aspectj.ExtensionInfo {
	
	public static BaseParser parser;
	
	public static final ID VISITOR_DUDU_01 = new Pass.ID("Visitor-Dudu-01");
	public static final ID FINISHED_DUDU_01 = new Pass.ID("finished-Dudu-01");
	public static final ID VISITOR_DUDU_02 = new Pass.ID("Visitor-Dudu-02");
	public static final ID FINISHED_DUDU_02 = new Pass.ID("finished-Dudu-02");
	public static final ID VISITOR_GIORGIO_01 = new Pass.ID("Visitor-Giorgio-01");
	public static final ID FINISHED_GIORGIO_01 = new Pass.ID("finished-Giorgio-01");
/*	
	public static final ID COLLECTION_PASS = new Pass.ID("collection-pass");
	public static final ID FINISHED_COLLECTION_PASS = new Pass.ID("finished-collection-pass");
	public static final ID GENERATE_CODE_PASS = new Pass.ID("generate-code-pass");
	public static final ID FINISHED_GENERATE_CODE_PASS = new Pass.ID("finished-generate-code-pass");
	public static final ID GENERATE_PPG_PASS = new Pass.ID("generate-ppg-pass");
	public static final ID FINISHED_GENERATE_PPG_PASS = new Pass.ID("finished-generate-ppg-pass");
	public static final ID XAJ_TYPECHECKER_PASS = new Pass.ID("xaj-typechecker-pass");
	public static final ID FINISHED_XAJ_TYPECHECKER_PASS = new Pass.ID("finished-xaj-typechecker-pass");
*/	
	
	private static ErrorQueue FilaErros;
	
	public static ErrorQueue getFilaErros() {
		return FilaErros;
	}
	
	public ExtensionInfo(Collection<String> jar_classes, Collection<String> aspect_sources) {
		super(jar_classes, aspect_sources);
	}

	static {
        // force Topics to load
        new Topics();
    }
	
	//Nome do compilador do syntaxclass
	public String compilerName() {
		return "metaxaj";
	}
	
	//Retorna o parser do syntaxclass
	public Parser parser(Reader reader, FileSource source, ErrorQueue eq) {
		FilaErros = eq;
        Lexer lexer = new Lexer_c(reader, source.path(), eq);
        Grm grm = new Grm(lexer, ts, nf, eq);
        parser = grm;
        return new CupParser(grm, source, eq);
    }
	
	//Retorna o fabrica de nó do syntaxclass
    protected NodeFactory createNodeFactory() {
        return new SCNodeFactory_c();
    }

    //Retorna o sistema de tipos do syntaxclass
    protected TypeSystem createTypeSystem() {
        return new SCTypeSystem_c();
    }
	
    public List<Pass> passes(Job job) {
    	List<Pass> passes =	super.passes(job);
    	/*
    	afterPass(passes, Pass.PARSE, new VisitorPass(XAJ_TYPECHECKER_PASS, job,
		          new TypeChecker(job, typeSystem(), nodeFactory())));
    	afterPass(passes, XAJ_TYPECHECKER_PASS, new	GlobalBarrierPass(FINISHED_XAJ_TYPECHECKER_PASS, job));
    	afterPass(passes, FINISHED_XAJ_TYPECHECKER_PASS, new VisitorPass(COLLECTION_PASS, job,
		          new CollectorVisitor(job, typeSystem(), nodeFactory())));  	   	
		afterPass(passes, COLLECTION_PASS, new	GlobalBarrierPass(FINISHED_COLLECTION_PASS, job));		
		afterPass(passes, FINISHED_COLLECTION_PASS, new VisitorPass(GENERATE_CODE_PASS, job,
		          new GenerateCode (job, typeSystem(), nodeFactory())));
		afterPass(passes, GENERATE_CODE_PASS, new	GlobalBarrierPass(FINISHED_GENERATE_CODE_PASS,
				job));
		afterPass(passes, FINISHED_GENERATE_CODE_PASS, new VisitorPass(GENERATE_PPG_PASS, job,
		          new GeneratePPGFile (job, typeSystem(), nodeFactory())));
		afterPass(passes, GENERATE_PPG_PASS, new	GlobalBarrierPass(FINISHED_GENERATE_PPG_PASS,
				job));
		*/
    	Visitor_Dudu_01 vd1 = new Visitor_Dudu_01(job, typeSystem(), nodeFactory());
    	afterPass(passes, Pass.PARSE, new VisitorPass(VISITOR_DUDU_01, job, vd1));
    	afterPass(passes, VISITOR_DUDU_01, new GlobalBarrierPass(FINISHED_DUDU_01, job));
    	afterPass(passes, FINISHED_DUDU_01, new VisitorPass(VISITOR_DUDU_02, job, new Visitor_Dudu_02(job, typeSystem(), nodeFactory(), vd1)));
    	afterPass(passes, VISITOR_DUDU_02, new GlobalBarrierPass(FINISHED_DUDU_02, job));
    	afterPass(passes, FINISHED_DUDU_02, new VisitorPass(VISITOR_GIORGIO_01, job, new Visitor_Giorgio_01(job, typeSystem(), nodeFactory())));
    	afterPass(passes, VISITOR_GIORGIO_01, new GlobalBarrierPass(FINISHED_GIORGIO_01, job));
    	
    	//Passe que imprime o código gerado na pasta output
    	passes.add(new OutputPass(Pass.OUTPUT, job,
                new Translator(job, ts, nf, targetFactory())));
    	return passes;
    }
    
    protected Options createOptions() {
    	return new Options(this);
    }
    
    public String[] defaultFileExtensions() {
        String [] extnames = {"aj", "java", "sc"};
        return extnames;
     }

}
